summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorliamwhite <liamwhite@users.noreply.github.com>2023-02-18 22:25:48 +0100
committerGitHub <noreply@github.com>2023-02-18 22:25:48 +0100
commite531d1fae986addc7253e14bcc569c38ab50ccb0 (patch)
tree82b68c763271ac1d15112a536136f7462cacadfb
parentMerge pull request #9825 from liamwhite/object-name (diff)
parentinput_common: Split mouse input into individual devices (diff)
downloadyuzu-e531d1fae986addc7253e14bcc569c38ab50ccb0.tar
yuzu-e531d1fae986addc7253e14bcc569c38ab50ccb0.tar.gz
yuzu-e531d1fae986addc7253e14bcc569c38ab50ccb0.tar.bz2
yuzu-e531d1fae986addc7253e14bcc569c38ab50ccb0.tar.lz
yuzu-e531d1fae986addc7253e14bcc569c38ab50ccb0.tar.xz
yuzu-e531d1fae986addc7253e14bcc569c38ab50ccb0.tar.zst
yuzu-e531d1fae986addc7253e14bcc569c38ab50ccb0.zip
-rw-r--r--src/core/hid/emulated_console.cpp3
-rw-r--r--src/core/hid/emulated_devices.cpp3
-rw-r--r--src/input_common/drivers/mouse.cpp67
-rw-r--r--src/input_common/drivers/mouse.h38
-rw-r--r--src/input_common/input_mapping.cpp4
-rw-r--r--src/yuzu/bootmanager.cpp30
-rw-r--r--src/yuzu/bootmanager.h2
-rw-r--r--src/yuzu/configuration/configure_input_player.cpp2
-rw-r--r--src/yuzu/configuration/configure_ringcon.cpp2
-rw-r--r--src/yuzu/main.cpp8
-rw-r--r--src/yuzu_cmd/emu_window/emu_window_sdl2.cpp8
11 files changed, 120 insertions, 47 deletions
diff --git a/src/core/hid/emulated_console.cpp b/src/core/hid/emulated_console.cpp
index 1c91bbe40..17d663379 100644
--- a/src/core/hid/emulated_console.cpp
+++ b/src/core/hid/emulated_console.cpp
@@ -23,7 +23,8 @@ void EmulatedConsole::SetTouchParams() {
// We can't use mouse as touch if native mouse is enabled
if (!Settings::values.mouse_enabled) {
- touch_params[index++] = Common::ParamPackage{"engine:mouse,axis_x:10,axis_y:11,button:0"};
+ touch_params[index++] =
+ Common::ParamPackage{"engine:mouse,axis_x:0,axis_y:1,button:0,port:2"};
}
touch_params[index++] =
diff --git a/src/core/hid/emulated_devices.cpp b/src/core/hid/emulated_devices.cpp
index 836f32c0f..578a6ff61 100644
--- a/src/core/hid/emulated_devices.cpp
+++ b/src/core/hid/emulated_devices.cpp
@@ -34,9 +34,12 @@ void EmulatedDevices::ReloadInput() {
// First two axis are reserved for mouse position
key_index = 2;
for (auto& mouse_device : mouse_analog_devices) {
+ // Mouse axis are only mapped on port 1, pad 0
Common::ParamPackage mouse_params;
mouse_params.Set("engine", "mouse");
mouse_params.Set("axis", static_cast<int>(key_index));
+ mouse_params.Set("port", 1);
+ mouse_params.Set("pad", 0);
mouse_device = Common::Input::CreateInputDevice(mouse_params);
key_index++;
}
diff --git a/src/input_common/drivers/mouse.cpp b/src/input_common/drivers/mouse.cpp
index faf9cbdc3..da50e0a24 100644
--- a/src/input_common/drivers/mouse.cpp
+++ b/src/input_common/drivers/mouse.cpp
@@ -15,23 +15,39 @@ constexpr int mouse_axis_y = 1;
constexpr int wheel_axis_x = 2;
constexpr int wheel_axis_y = 3;
constexpr int motion_wheel_y = 4;
-constexpr int touch_axis_x = 10;
-constexpr int touch_axis_y = 11;
constexpr PadIdentifier identifier = {
.guid = Common::UUID{},
.port = 0,
.pad = 0,
};
+constexpr PadIdentifier real_mouse_identifier = {
+ .guid = Common::UUID{},
+ .port = 1,
+ .pad = 0,
+};
+
+constexpr PadIdentifier touch_identifier = {
+ .guid = Common::UUID{},
+ .port = 2,
+ .pad = 0,
+};
+
Mouse::Mouse(std::string input_engine_) : InputEngine(std::move(input_engine_)) {
PreSetController(identifier);
+ PreSetController(real_mouse_identifier);
+ PreSetController(touch_identifier);
+
+ // Initialize all mouse axis
PreSetAxis(identifier, mouse_axis_x);
PreSetAxis(identifier, mouse_axis_y);
PreSetAxis(identifier, wheel_axis_x);
PreSetAxis(identifier, wheel_axis_y);
PreSetAxis(identifier, motion_wheel_y);
- PreSetAxis(identifier, touch_axis_x);
- PreSetAxis(identifier, touch_axis_y);
+ PreSetAxis(real_mouse_identifier, mouse_axis_x);
+ PreSetAxis(real_mouse_identifier, mouse_axis_y);
+ PreSetAxis(touch_identifier, mouse_axis_x);
+ PreSetAxis(touch_identifier, mouse_axis_y);
update_thread = std::jthread([this](std::stop_token stop_token) { UpdateThread(stop_token); });
}
@@ -39,7 +55,7 @@ void Mouse::UpdateThread(std::stop_token stop_token) {
Common::SetCurrentThreadName("Mouse");
constexpr int update_time = 10;
while (!stop_token.stop_requested()) {
- if (Settings::values.mouse_panning && !Settings::values.mouse_enabled) {
+ if (Settings::values.mouse_panning) {
// Slow movement by 4%
last_mouse_change *= 0.96f;
const float sensitivity =
@@ -57,17 +73,7 @@ void Mouse::UpdateThread(std::stop_token stop_token) {
}
}
-void Mouse::MouseMove(int x, int y, f32 touch_x, f32 touch_y, int center_x, int center_y) {
- // If native mouse is enabled just set the screen coordinates
- if (Settings::values.mouse_enabled) {
- SetAxis(identifier, mouse_axis_x, touch_x);
- SetAxis(identifier, mouse_axis_y, touch_y);
- return;
- }
-
- SetAxis(identifier, touch_axis_x, touch_x);
- SetAxis(identifier, touch_axis_y, touch_y);
-
+void Mouse::Move(int x, int y, int center_x, int center_y) {
if (Settings::values.mouse_panning) {
auto mouse_change =
(Common::MakeVec(x, y) - Common::MakeVec(center_x, center_y)).Cast<float>();
@@ -113,20 +119,41 @@ void Mouse::MouseMove(int x, int y, f32 touch_x, f32 touch_y, int center_x, int
}
}
-void Mouse::PressButton(int x, int y, f32 touch_x, f32 touch_y, MouseButton button) {
- SetAxis(identifier, touch_axis_x, touch_x);
- SetAxis(identifier, touch_axis_y, touch_y);
+void Mouse::MouseMove(f32 touch_x, f32 touch_y) {
+ SetAxis(real_mouse_identifier, mouse_axis_x, touch_x);
+ SetAxis(real_mouse_identifier, mouse_axis_y, touch_y);
+}
+
+void Mouse::TouchMove(f32 touch_x, f32 touch_y) {
+ SetAxis(touch_identifier, mouse_axis_x, touch_x);
+ SetAxis(touch_identifier, mouse_axis_y, touch_y);
+}
+
+void Mouse::PressButton(int x, int y, MouseButton button) {
SetButton(identifier, static_cast<int>(button), true);
+
// Set initial analog parameters
mouse_origin = {x, y};
last_mouse_position = {x, y};
button_pressed = true;
}
+void Mouse::PressMouseButton(MouseButton button) {
+ SetButton(real_mouse_identifier, static_cast<int>(button), true);
+}
+
+void Mouse::PressTouchButton(f32 touch_x, f32 touch_y, MouseButton button) {
+ SetAxis(touch_identifier, mouse_axis_x, touch_x);
+ SetAxis(touch_identifier, mouse_axis_y, touch_y);
+ SetButton(touch_identifier, static_cast<int>(button), true);
+}
+
void Mouse::ReleaseButton(MouseButton button) {
SetButton(identifier, static_cast<int>(button), false);
+ SetButton(real_mouse_identifier, static_cast<int>(button), false);
+ SetButton(touch_identifier, static_cast<int>(button), false);
- if (!Settings::values.mouse_panning && !Settings::values.mouse_enabled) {
+ if (!Settings::values.mouse_panning) {
SetAxis(identifier, mouse_axis_x, 0);
SetAxis(identifier, mouse_axis_y, 0);
}
diff --git a/src/input_common/drivers/mouse.h b/src/input_common/drivers/mouse.h
index 72073cc23..f3b65bdd1 100644
--- a/src/input_common/drivers/mouse.h
+++ b/src/input_common/drivers/mouse.h
@@ -37,13 +37,43 @@ public:
* @param center_x the x-coordinate of the middle of the screen
* @param center_y the y-coordinate of the middle of the screen
*/
- void MouseMove(int x, int y, f32 touch_x, f32 touch_y, int center_x, int center_y);
+ void Move(int x, int y, int center_x, int center_y);
/**
- * Sets the status of all buttons bound with the key to pressed
- * @param key_code the code of the key to press
+ * Signals that real mouse has moved.
+ * @param x the absolute position on the touchscreen of the cursor
+ * @param y the absolute position on the touchscreen of the cursor
*/
- void PressButton(int x, int y, f32 touch_x, f32 touch_y, MouseButton button);
+ void MouseMove(f32 touch_x, f32 touch_y);
+
+ /**
+ * Signals that touch finger has moved.
+ * @param x the absolute position on the touchscreen of the cursor
+ * @param y the absolute position on the touchscreen of the cursor
+ */
+ void TouchMove(f32 touch_x, f32 touch_y);
+
+ /**
+ * Sets the status of a button to pressed
+ * @param x the x-coordinate of the cursor
+ * @param y the y-coordinate of the cursor
+ * @param button the id of the button to press
+ */
+ void PressButton(int x, int y, MouseButton button);
+
+ /**
+ * Sets the status of a mouse button to pressed
+ * @param button the id of the button to press
+ */
+ void PressMouseButton(MouseButton button);
+
+ /**
+ * Sets the status of touch finger to pressed
+ * @param x the absolute position on the touchscreen of the cursor
+ * @param y the absolute position on the touchscreen of the cursor
+ * @param button the id of the button to press
+ */
+ void PressTouchButton(f32 touch_x, f32 touch_y, MouseButton button);
/**
* Sets the status of all buttons bound with the key to released
diff --git a/src/input_common/input_mapping.cpp b/src/input_common/input_mapping.cpp
index d6e49d2c5..6990a86b9 100644
--- a/src/input_common/input_mapping.cpp
+++ b/src/input_common/input_mapping.cpp
@@ -194,6 +194,10 @@ bool MappingFactory::IsDriverValid(const MappingData& data) const {
if (data.engine == "keyboard" && data.pad.port != 0) {
return false;
}
+ // Only port 0 can be mapped on the mouse
+ if (data.engine == "mouse" && data.pad.port != 0) {
+ return false;
+ }
// To prevent mapping with two devices we disable any UDP except motion
if (!Settings::values.enable_udp_controller && data.engine == "cemuhookudp" &&
data.type != EngineInputType::Motion) {
diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp
index 352300e88..17acd3933 100644
--- a/src/yuzu/bootmanager.cpp
+++ b/src/yuzu/bootmanager.cpp
@@ -401,12 +401,6 @@ qreal GRenderWindow::windowPixelRatio() const {
return devicePixelRatioF();
}
-std::pair<u32, u32> GRenderWindow::ScaleTouch(const QPointF& pos) const {
- const qreal pixel_ratio = windowPixelRatio();
- return {static_cast<u32>(std::max(std::round(pos.x() * pixel_ratio), qreal{0.0})),
- static_cast<u32>(std::max(std::round(pos.y() * pixel_ratio), qreal{0.0}))};
-}
-
void GRenderWindow::closeEvent(QCloseEvent* event) {
emit Closed();
QWidget::closeEvent(event);
@@ -649,10 +643,12 @@ void GRenderWindow::mousePressEvent(QMouseEvent* event) {
// Qt sometimes returns the parent coordinates. To avoid this we read the global mouse
// coordinates and map them to the current render area
const auto pos = mapFromGlobal(QCursor::pos());
- const auto [x, y] = ScaleTouch(pos);
- const auto [touch_x, touch_y] = MapToTouchScreen(x, y);
+ const auto [touch_x, touch_y] = MapToTouchScreen(pos.x(), pos.y());
const auto button = QtButtonToMouseButton(event->button());
- input_subsystem->GetMouse()->PressButton(x, y, touch_x, touch_y, button);
+
+ input_subsystem->GetMouse()->PressMouseButton(button);
+ input_subsystem->GetMouse()->PressButton(pos.x(), pos.y(), button);
+ input_subsystem->GetMouse()->PressTouchButton(touch_x, touch_y, button);
emit MouseActivity();
}
@@ -665,11 +661,13 @@ void GRenderWindow::mouseMoveEvent(QMouseEvent* event) {
// Qt sometimes returns the parent coordinates. To avoid this we read the global mouse
// coordinates and map them to the current render area
const auto pos = mapFromGlobal(QCursor::pos());
- const auto [x, y] = ScaleTouch(pos);
- const auto [touch_x, touch_y] = MapToTouchScreen(x, y);
+ const auto [touch_x, touch_y] = MapToTouchScreen(pos.x(), pos.y());
const int center_x = width() / 2;
const int center_y = height() / 2;
- input_subsystem->GetMouse()->MouseMove(x, y, touch_x, touch_y, center_x, center_y);
+
+ input_subsystem->GetMouse()->MouseMove(touch_x, touch_y);
+ input_subsystem->GetMouse()->TouchMove(touch_x, touch_y);
+ input_subsystem->GetMouse()->Move(pos.x(), pos.y(), center_x, center_y);
if (Settings::values.mouse_panning && !Settings::values.mouse_enabled) {
QCursor::setPos(mapToGlobal(QPoint{center_x, center_y}));
@@ -697,8 +695,8 @@ void GRenderWindow::wheelEvent(QWheelEvent* event) {
void GRenderWindow::TouchBeginEvent(const QTouchEvent* event) {
QList<QTouchEvent::TouchPoint> touch_points = event->touchPoints();
for (const auto& touch_point : touch_points) {
- const auto [x, y] = ScaleTouch(touch_point.pos());
- const auto [touch_x, touch_y] = MapToTouchScreen(x, y);
+ const auto pos = touch_point.pos();
+ const auto [touch_x, touch_y] = MapToTouchScreen(pos.x(), pos.y());
input_subsystem->GetTouchScreen()->TouchPressed(touch_x, touch_y, touch_point.id());
}
}
@@ -707,8 +705,8 @@ void GRenderWindow::TouchUpdateEvent(const QTouchEvent* event) {
QList<QTouchEvent::TouchPoint> touch_points = event->touchPoints();
input_subsystem->GetTouchScreen()->ClearActiveFlag();
for (const auto& touch_point : touch_points) {
- const auto [x, y] = ScaleTouch(touch_point.pos());
- const auto [touch_x, touch_y] = MapToTouchScreen(x, y);
+ const auto pos = touch_point.pos();
+ const auto [touch_x, touch_y] = MapToTouchScreen(pos.x(), pos.y());
input_subsystem->GetTouchScreen()->TouchMoved(touch_x, touch_y, touch_point.id());
}
input_subsystem->GetTouchScreen()->ReleaseInactiveTouch();
diff --git a/src/yuzu/bootmanager.h b/src/yuzu/bootmanager.h
index 092c6206f..627e19f42 100644
--- a/src/yuzu/bootmanager.h
+++ b/src/yuzu/bootmanager.h
@@ -184,8 +184,6 @@ public:
void CaptureScreenshot(const QString& screenshot_path);
- std::pair<u32, u32> ScaleTouch(const QPointF& pos) const;
-
/**
* Instructs the window to re-launch the application using the specified program_index.
* @param program_index Specifies the index within the application of the program to launch.
diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp
index 723690e71..50b62293e 100644
--- a/src/yuzu/configuration/configure_input_player.cpp
+++ b/src/yuzu/configuration/configure_input_player.cpp
@@ -1490,7 +1490,7 @@ void ConfigureInputPlayer::mousePressEvent(QMouseEvent* event) {
}
const auto button = GRenderWindow::QtButtonToMouseButton(event->button());
- input_subsystem->GetMouse()->PressButton(0, 0, 0, 0, button);
+ input_subsystem->GetMouse()->PressButton(0, 0, button);
}
void ConfigureInputPlayer::wheelEvent(QWheelEvent* event) {
diff --git a/src/yuzu/configuration/configure_ringcon.cpp b/src/yuzu/configuration/configure_ringcon.cpp
index 1275f10c8..71afbc423 100644
--- a/src/yuzu/configuration/configure_ringcon.cpp
+++ b/src/yuzu/configuration/configure_ringcon.cpp
@@ -371,7 +371,7 @@ void ConfigureRingController::mousePressEvent(QMouseEvent* event) {
}
const auto button = GRenderWindow::QtButtonToMouseButton(event->button());
- input_subsystem->GetMouse()->PressButton(0, 0, 0, 0, button);
+ input_subsystem->GetMouse()->PressButton(0, 0, button);
}
void ConfigureRingController::keyPressEvent(QKeyEvent* event) {
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 5560a30bd..f233b065e 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -1165,6 +1165,14 @@ void GMainWindow::InitializeHotkeys() {
Settings::values.use_speed_limit.SetValue(!Settings::values.use_speed_limit.GetValue());
});
connect_shortcut(QStringLiteral("Toggle Mouse Panning"), [&] {
+ if (Settings::values.mouse_enabled) {
+ Settings::values.mouse_panning = false;
+ QMessageBox::warning(
+ this, tr("Emulated mouse is enabled"),
+ tr("Real mouse input and mouse panning are incompatible. Please disable the "
+ "emulated mouse in input advanced settings to allow mouse panning."));
+ return;
+ }
Settings::values.mouse_panning = !Settings::values.mouse_panning;
if (Settings::values.mouse_panning) {
render_window->installEventFilter(render_window);
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp
index 5450b8c38..5153cdb79 100644
--- a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp
+++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp
@@ -62,7 +62,9 @@ void EmuWindow_SDL2::OnMouseButton(u32 button, u8 state, s32 x, s32 y) {
const auto mouse_button = SDLButtonToMouseButton(button);
if (state == SDL_PRESSED) {
const auto [touch_x, touch_y] = MouseToTouchPos(x, y);
- input_subsystem->GetMouse()->PressButton(x, y, touch_x, touch_y, mouse_button);
+ input_subsystem->GetMouse()->PressButton(x, y, mouse_button);
+ input_subsystem->GetMouse()->PressMouseButton(mouse_button);
+ input_subsystem->GetMouse()->PressTouchButton(touch_x, touch_y, mouse_button);
} else {
input_subsystem->GetMouse()->ReleaseButton(mouse_button);
}
@@ -70,7 +72,9 @@ void EmuWindow_SDL2::OnMouseButton(u32 button, u8 state, s32 x, s32 y) {
void EmuWindow_SDL2::OnMouseMotion(s32 x, s32 y) {
const auto [touch_x, touch_y] = MouseToTouchPos(x, y);
- input_subsystem->GetMouse()->MouseMove(x, y, touch_x, touch_y, 0, 0);
+ input_subsystem->GetMouse()->Move(x, y, 0, 0);
+ input_subsystem->GetMouse()->MouseMove(touch_x, touch_y);
+ input_subsystem->GetMouse()->TouchMove(touch_x, touch_y);
}
void EmuWindow_SDL2::OnFingerDown(float x, float y, std::size_t id) {